package com.hyy.listener;

import com.hyy.common.constant.Constants;
import com.hyy.common.utils.JsonUtil;
import com.hyy.common.utils.Mail;
import com.hyy.dataobject.UserInfo;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.implementation.bind.annotation.BindingPriority;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 用户队列监听器
 * 负责监听用户注册事件，并发送欢迎邮件
 * 同时处理队列与交换机的声明和绑定关系
 */
@Component
@Slf4j
public class UserQueueListener {

    @Autowired
    private Mail mail;

//    //queues指定需要消费的消息名称
//    @RabbitListener(queues= Constants.USER_QUEUE_NAME)
//    public void hander(Message message, Channel channel) throws IOException {
//
//        //这个变量可以认为是mq的唯一ID（channel上唯一）
//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
//
//        try{
//            //确认收到消息
//            String body=new String(message.getBody());
//            log.info("收到用户信息");
//
//            //TODO 发送注册成功邮件
//
//            //接下来需要告诉broker消费者已经收到了消息，因为配置了手动确认
//            //true是 进行批量确认
//            channel.basicAck(deliveryTag,true);
//        }catch (Exception e){
//
//            //否定确认
//            // 第二个是进行批量确认 第三个参数是 是否重新发送消息
//            channel.basicNack(deliveryTag,true,true);
//            log.error("右键发送失败，e:{}",e.getMessage());
//        }
//    }

    /**
     * 用户注册消息队列监听处理方法（消费者）
     * 通过@RabbitListener注解声明队列与交换机的绑定关系，并处理接收到的消息
     * 
     * 绑定关系说明：
     * 1. 队列：USER_QUEUE_NAME，持久化
     * 2. 交换机：USER_EXCHANGE_NAME，类型为扇形(FANOUT)，持久化
     * 
     * @param message 接收到的消息对象
     * @param channel RabbitMQ通道，用于消息确认
     * @throws IOException 消息处理过程中可能发生IO异常
     */
    @RabbitListener(bindings=@QueueBinding(
            //队列名字是value

            //注意durable默认是true

            //声明队列的名字,以及是否进行持久化
            value=@Queue(value=Constants.USER_QUEUE_NAME,durable="true"),
            //声明交换机名字,是否持久化
            exchange = @Exchange(value=Constants.USER_EXCHANGE_NAME,durable = "true",type= ExchangeTypes.FANOUT)

            //交换机是exchange

    ))
    public void hander(Message message, Channel channel) throws IOException {

        //这个变量可以认为是mq的唯一ID（channel上唯一）
        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        try{
            //确认收到消息
            String body=new String(message.getBody());
            log.info("收到用户信息");

            //发送注册成功邮件
            UserInfo userInfo= JsonUtil.parseJson(body, UserInfo.class);
            mail.send(userInfo.getEmail(),"欢迎您注册博客系统",buildContent(userInfo.getUserName()));

            //接下来需要告诉broker消费者已经收到了消息，因为配置了手动确认
            //true是 进行批量确认
            channel.basicAck(deliveryTag,true);
        }catch (Exception e){

            //否定确认
            // 第二个是进行批量确认 第三个参数是 是否重新发送消息
            channel.basicNack(deliveryTag,true,true);
            log.error("右键发送失败，e:{}",e.getMessage());
        }
    }

    /**
     * 构建邮件内容
     * 根据用户名生成欢迎邮件的HTML内容
     * 
     * @param userName 用户名
     * @return 格式化的HTML邮件内容
     */
    private String buildContent(String userName){
        StringBuilder builder = new StringBuilder();
        builder.append("尊敬的").append(userName).append("，你好").append("<br/>");
        builder.append("欢迎您以加入我们的博客社区，您已成为尊敬的会员！<br/>");
        builder.append("您的注册信息如下：用户名：").append("userName").append("<br/>");
        builder.append("**小灰灰博客团队**").append("<br/>");
        return builder.toString();

    }
}


